package com.googlecode.dgwt.rebind.feature;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.google.gwt.core.ext.typeinfo.JClassType;


/**
 * @author      Wellington Tadeu dos Santos
 * @since       DGWT v0.01
 */
public class ClassInfo {

    public static final int GEN_NONE = 0;
    public static final int GEN_AUTO = 1;
    public static final int GEN_COPY = 1;

    
    public JClassType type;
    
    public JClassType typeIntf;
    
    private String getterName;
    
    private String newClassName;
    
    private ClassInfo assignedImpl;
    
    public List<MethodInfo> methods;
    
    public List<InterfaceInfo> interfaces;
    
    public Map<InterfaceInfo, ClassInfo> inherits;

    public List<ClassInfo> superClasses;
    
    public List<FieldInjection> injections = new ArrayList<FieldInjection>();
    
    public int generationType = GEN_NONE;

    

    public ClassInfo(JClassType type, JClassType typeIntf){
        this.type = type;
        this.typeIntf = typeIntf;
    }
    
    public void setGeneratedNames(ClassInfo targetInfo, int id) {
        if (this.generationType == GEN_NONE) {
            this.generationType = GEN_AUTO;
            this.assignedImpl = null;
            
            this.setGetterName("___" + this.type.getName().toLowerCase().replace('.', '_') + "_" + id);
            
            if (needsRebind()) {
                this.setNewClassName(targetInfo.getNewClassName() + this.getGetterName());
            } 
            else {
                this.setNewClassName(type.getQualifiedSourceName());
            }
        }
    }
    
    public void setNamesFrom(ClassInfo item) {
        this.generationType = GEN_COPY;
        this.assignedImpl = item;
    }
    
    public void setInherit(InterfaceInfo intf, ClassInfo classInfo) {
        ClassInfo currInfo = inherits.get(intf);
        if (currInfo == null) {
            inherits.put(intf, classInfo);
        }
    }

    public boolean needsRebind() {
        return true;//type.isAbstract() || !superClasses.isEmpty() || !injections.isEmpty();
    }

    public void setGetterName(String getterName) {
        this.getterName = getterName;
    }

    public String getGetterName() {
        if (this.assignedImpl != null) { 
            return assignedImpl.getGetterName();
        }
        return getterName;
    }

    public void setNewClassName(String newClassName) {
        this.newClassName = newClassName;
    }

    public String getNewClassName() {
        if (this.assignedImpl != null) { 
            return assignedImpl.getNewClassName();
        }
        return newClassName;
    }

    public boolean hasStub() {
        return type != typeIntf;
    }

}
